package com.caiyi.financial.nirvana.sms.filters;

import com.alibaba.fastjson.JSON;
import com.caiyi.financial.nirvana.sms.entity.SmsUser;
import com.caiyi.financial.nirvana.sms.enums.ReturnCodeEnum;
import com.caiyi.financial.nirvana.sms.enums.SmsUserChargeTypeEnum;
import com.caiyi.financial.nirvana.sms.jedis.JedisKey;
import com.caiyi.financial.nirvana.sms.jedis.JedisService;
import com.caiyi.financial.nirvana.sms.param.SendMsgParam;
import com.caiyi.financial.nirvana.sms.queue.AlarmSendQueueEntity;
import com.caiyi.financial.nirvana.sms.util.CommUtil;
import com.caiyi.financial.nirvana.sms.util.Constant;
import com.youyu.common.utils.YyAssert;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by Mario on 2017/12/19 0019.
 * 余额验证，扣款Filter
 */
public class BalanceFilter implements Filter {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 实现Run
     *
     * @param filterChain 过滤链对象
     */
    @Override
    public void run(FilterChain filterChain) {
        SendMsgParam sendMsgParam = filterChain.getParam();
        //余额校验
        SmsUser user = filterChain.getSmsUser();
        Integer msgCount = filterChain.getPhones().size() * CommUtil.splitLongContent(sendMsgParam.getContent()).size();
        /*
         * 预付费账户检测余额是否充足
         * 后付费用户直接增加短信发送数量
         */
        YyAssert.isFalse(user.getChargeType() == SmsUserChargeTypeEnum.BEFORE.index && user.getSmsNum() < msgCount, ReturnCodeEnum.BALANCE_ERROR);
        //扣款，更新至Redis
        String key = String.format(JedisKey.SMS_BALANCE, user.getAccount());
        long count = JedisService.incrBy(key, -msgCount);
        //扣款，添加操作到数据库更新队列
        JedisService.lpush(JedisKey.SMS_QUEUE_BALANCE_UPDATE, user.getId() + "=" + (-msgCount));
        //余额提醒
        remindMsgCount(user, count);

        filterChain.doFilter();
    }

    private void remindMsgCount(SmsUser user, long count) {
        try {
            String phone = user.getRemindPhone();
            Integer remindCount = user.getRemindValue();
            if (StringUtils.isBlank(phone)) {
                return;
            }
            if (remindCount == null || count >= remindCount) {
                return;
            }
            String key = String.format(JedisKey.SMS_REMIND_COUNT_ACCOUNT, user.getAccount());
            if (JedisService.exists(key)) {
                logger.info("account {} it has been reminding within 24 hours", user.getAccount());
                return;
            }
            AlarmSendQueueEntity entity = new AlarmSendQueueEntity();
            entity.setPhone(user.getRemindPhone());
            String content = String.format(Constant.SMS_REMIND_CONTENT, user.getAccount(), count, remindCount);
            entity.setContent(content);
            JedisService.lpush(JedisKey.SMS_QUEUE_ALARM_MSG_SEND, JSON.toJSONString(entity));
            JedisService.set(key, "1");
            JedisService.expire(key, Constant.DAY_OF_SECOND);
            logger.info("send reminding sms phone : {}, account : {}", phone, user.getAccount());
        } catch (Exception e) {
            logger.error("BalanceFilter remindMsgCount error ! ", e);
        }
    }
}
